using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using TestWebApi.Models;

namespace TestWebApi.Util;

public class JwtHelper
{
     /// <summary>
    /// Generate JWT token
    /// </summary>
    private readonly IConfiguration _configuration;

    private readonly int _expirationMinutes; // 过期时间
    private readonly SymmetricSecurityKey _key; // 密钥

    public JwtHelper(IConfiguration configuration)
    {
        _configuration = configuration;
        var secretKey = _configuration["Jwt:SecretKey"]
                        ?? throw new InvalidOperationException("JWT SecretKey 未配置");

        _key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
        _expirationMinutes = int.TryParse(_configuration["Jwt:Expiration"], out int exp) ? exp : 60; // 默认60分钟
    }

    /// <summary>
    /// 生成token
    /// </summary>
    /// <param name="user">用户信息</param>
    /// <returns></returns>
    public string GenerateToken(LoginModel user)
    {
        var claims = new[]
        {
            new Claim(ClaimTypes.Name, user.UserName),
            new Claim(ClaimTypes.Role, user.Role.ToString()),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), // JWT ID
            new Claim("Email", user.Email), //自定义声明
            new Claim("UserName", user.UserName) //自定义声明
        };
        var secretary = _configuration["Jwt:SecretKey"] ?? string.Empty;
        //如果为空或者长度不足16位，则生成32位随机密钥
        if (string.IsNullOrEmpty(secretary) || Encoding.UTF8.GetBytes(secretary).Length < 16)
        {
            // 生成32位默认密钥
            secretary = "2c9341ca4cf3d87b9e4eb905d6a3ec45";
            // secretary = secretary.PadRight(32, 'a');
        }

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretary)); // 对称密钥密钥
        var signingCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); // 使用HMAC SHA256加密算法
        var token = new JwtSecurityToken(
            issuer: _configuration["Jwt:Issuer"],
            audience: _configuration["Jwt:Audience"],
            claims: claims, //载荷
            expires: DateTime.UtcNow.AddMinutes(_expirationMinutes), //过期时间
            signingCredentials: signingCredentials //签名
        );
        return new JwtSecurityTokenHandler().WriteToken(token);
    }
}